# 控制传送带
# 当红外没有检测到，移动传送带
# 自动模式下，没有盒子就会移动，
# 非自动模式，手动开关
import sys
import threading
import time

from PyQt5.QtCore import pyqtSignal, QObject
# from gpiozero import LED, Button
# from gpiozero.pins.rpigpio import RPiGPIOFactory
from loguru import logger

import Devices
from Arm import Arm
from singleton import singleton


class ConveyorBelt(object):
    times = 5
    arm_safe_value = 100  # 机械臂的y轴位置 用于判断 传送带 和 机械臂是否相对冲突

    def __init__(self, conveyor_gpio, ir_gpio):
        # self.switch = LED(conveyor_gpio, pin_factory=RPiGPIOFactory())
        # self.ir = Button(ir_gpio, pin_factory=RPiGPIOFactory())

        self.auto = True
        self.on = False

        self.stop()

    def move(self):
        # self.on = True
        # self.switch.on()
        # Devices.digital_write(self.conveyor_gpio, 1)
        pass

    def stop(self):
        # self.on = False
        # self.switch.off()
        # Devices.digital_write(self.conveyor_gpio, 1)
        pass

    def off(self):
        self.auto = False

    def set_auto(self, state):
        self.auto = state

    def is_auto(self):
        return self.auto

    def is_on(self):
        return self.on

    def ir_state(self):
        # logger.info(self.ir.is_pressed)
        # return self.ir.is_pressed
        # return Devices.digital_read(self.ir_gpio)
        pass

    def update(self):
        # logger.info("{} {}".format(self.on, self.auto))
        if not self.on and self.auto:
            if not self.ir_state() and self.arm_outside_of_conveyor():
                self.move()
            else:
                self.stop()

    # 机械臂离开了传送带范围
    def arm_outside_of_conveyor(self):
        _, y, _ = Arm().get_pos()
        # logger.debug(y)
        if y <= self.arm_safe_value:
            return True

        return False

    def is_ready(self):
        return self.ir_state()


class ConveyorThread(threading.Thread):
    def __init__(self, conveyor, interval):
        super(ConveyorThread, self).__init__()
        self.conveyor = conveyor
        self.daemon = True
        self.interval = interval

    def run(self):
        # logger.info("self.interval {}".format(self.interval))
        while 1:
            try:
                # logger.info("elf.conveyor.update()".format(self.interval))
                # while self.boiler.bytes_available():
                self.conveyor.update()
                time.sleep(self.interval)
                # logger.info("elf.conveyor.update()".format(self.interval))
            except Exception as e:
                # catch 'error: Bad file descriptor'
                # iterate may be called while the serial port is being closed,
                # causing an "error: (9, 'Bad file descriptor')"
                if getattr(e, "errno", None) == 9:
                    break
                try:
                    if e[0] == 9:
                        break
                except (TypeError, IndexError):
                    pass
                raise
            except (KeyboardInterrupt):
                sys.exit()


@singleton
class ConveyorManager(QObject):
    conveyor_track_pos = [0, 300, 600, 900]

    sig_sensor_state = pyqtSignal(tuple)

    def __init__(self):
        super().__init__()
        self.conveyors = []
        self.conveyors.append(ConveyorBelt(6, 7))

        # for con in self.conveyors:
        # logger.info("loop")
        thread = ConveyorThread(self, 0.5)
        thread.start()

    def init(self):
        pass

    def count(self):
        return len(self.conveyors)

    def update(self):
        # logger.info("cb update")
        for con in self.conveyors:
            con.update()

        for i, con in enumerate(self.conveyors):
            self.sig_sensor_state.emit((i, con.is_on(), con.is_ready()))

    # 找到有瓶子的传送带
    # 返回位置标签
    def find_conveyor_with_bottle(self):
        for i, con in enumerate(self.conveyors):
            if con.is_ready():
                return i

        return 0

    def find_track_pos_with_bottle(self):
        index = self.find_conveyor_with_bottle()
        return self.conveyor_track_pos[index]
